package netective.gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

import org.jfree.chart.JFreeChart;

import netective.api.analyzer.PacketType;
import netective.api.analyzer.PredictionType;
import netective.gui.charts.ChartGrain;
import netective.gui.charts.ChartType;
import netective.gui.charts.TimeChartFactory;
import netective.gui.charts.TimeSeriesChart;

@SuppressWarnings("serial")
public class TimeSeriesChartPanel extends JPanel implements ActionListener {
	TimeSeriesChart chart;

	JPanel controlPanel;
	
	JCheckBox[] chartTypes;
	
	JComboBox grainSelector;
	
	JComboBox predictionSelector;
	
	JButton btnRefresh;
	
	ChartType chartType;
	
	public TimeSeriesChartPanel(TimeSeriesChart _chart, ChartType _chartType, PacketType[] packetTypes,
			ArrayList<PacketType> selectedTypes, ChartGrain chartGrain, PredictionType prediction) {
		this.chart = _chart;
		this.chartType = _chartType;
		
		controlPanel = new JPanel();
		controlPanel.setLayout(new FlowLayout());
		controlPanel.setMaximumSize(new Dimension(1000, 200));
		
		if (packetTypes == null) {
			packetTypes = PacketType.getAllPacketTypes();
		}
		
		JLabel lblPrediction = new JLabel("Analysis: ");
		predictionSelector = new JComboBox(PredictionType.GetAllPredictionTypes());
		predictionSelector.setSelectedItem(prediction);
		controlPanel.add(lblPrediction);
		controlPanel.add(predictionSelector);
		
		JLabel lblGrain = new JLabel("Granularity: ");
		grainSelector = new JComboBox(ChartGrain.GetAllGrains());
		grainSelector.setSelectedItem(chartGrain);
		controlPanel.add(lblGrain);
		controlPanel.add(grainSelector);
		
		createCheckBocSelector(packetTypes, selectedTypes);
		
		btnRefresh = new JButton("Refresh chart");
		btnRefresh.addActionListener(this);
		controlPanel.add(btnRefresh);
		
		this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		this.add(controlPanel, Component.TOP_ALIGNMENT);
		this.add(chart);
		this.setBorder(new LineBorder(Color.GRAY, 2));
	}

	private void createCheckBocSelector(PacketType[] packetTypes,
			ArrayList<PacketType> selectedTypes) {
		chartTypes = new JCheckBox[packetTypes.length];
		for (int i = 0; i < chartTypes.length; i++) {
			chartTypes[i] = new JCheckBox();
			chartTypes[i].setText(packetTypes[i].toString());
			if (selectedTypes.contains(packetTypes[i])) {
				chartTypes[i].setSelected(true);
			} else {
				chartTypes[i].setSelected(false);
			}
			controlPanel.add(chartTypes[i]);
		}
	}

	@Override
	public void actionPerformed(ActionEvent event) {
		if (event.getSource().equals(btnRefresh)) {
			
			ChartGrain grain = (ChartGrain) this.grainSelector.getSelectedItem();
			PredictionType prediction = (PredictionType) this.predictionSelector.getSelectedItem();
			
			TimeSeriesChart _chart = null;
			switch (chartType) {
			case ClassesOfPackets: _chart = TimeChartFactory.classesOfPackets(grain, prediction, this.getSelectedPackets());
				break;
			case DirectionOfPackets: _chart = TimeChartFactory.dirrectionOfPackets(grain, prediction, this.getSelectedPacketsToString());
				break;
			case DownloadUpload: _chart = TimeChartFactory.downloadUpload(grain, prediction, this.getSelectedPacketsToString());
				break;
			case DownloadUploadAverage: _chart = TimeChartFactory.downloadUploadAverage(grain, prediction, this.getSelectedPacketsToString());
				break;
			case OutPort: _chart = 	TimeChartFactory.outPort(grain, prediction, 10, this.getSelectedPacketsToString());
				break;
			case InPort: _chart = 	TimeChartFactory.inPort(grain, prediction, 10, this.getSelectedPacketsToString());
				break;
			case OtherPort: _chart = TimeChartFactory.otherPort(grain, prediction, 10, this.getSelectedPacketsToString());
				break;
			case OtherAdresses: _chart = TimeChartFactory.otherAdresses(grain, prediction, 10, this.getSelectedPacketsToString());
				break;
			}
			
			chart.setChart(_chart.getChart());

			this.repaint();	
		}
	}
	
	public void setChartAndRefresh(JFreeChart _chart) {
		chart.setChart(_chart);
		this.repaint();
	}

	public ArrayList<PacketType> getSelectedPackets() {
		ArrayList<PacketType> packetTypeArr = new ArrayList<PacketType>();
		for (int i = 0; i < chartTypes.length; i++) {
			if (chartTypes[i].isSelected()) {
				packetTypeArr.add(PacketType.convertFromString(chartTypes[i].getText()));
			}
		}
		
		return packetTypeArr;
	}
	
	public String getSelectedPacketsToString() {
		return getSelectedPacketsToString(getSelectedPackets());
	}
	
	public static String getSelectedPacketsToString(ArrayList<PacketType> packetTypes) {
		String selectedPackets = packetTypes.toString();
		selectedPackets = selectedPackets.replace("[", "('").replace("]", "')");
		selectedPackets = selectedPackets.replace(",", "',");
		selectedPackets = selectedPackets.replace(", ", ", '");
		
		return selectedPackets;
	}
	
	
	public TimeSeriesChart getChart() {
		return chart;
	}

	public void setChart(TimeSeriesChart chart) {
		this.chart = chart;
	}
	
	public ChartGrain getSelectedGrain() {
		return (ChartGrain) grainSelector.getSelectedItem();
	}
	
	public PredictionType getSelectedPrediction() {
		return (PredictionType) predictionSelector.getSelectedItem();
	}
}